package com.franklin.ideaplugin.easytesting.vfs;

import com.franklin.ideaplugin.easytesting.entity.ExecuteResult;
import com.franklin.ideaplugin.easytesting.ui.history.ExecuteHistoryFormNew;
import com.intellij.openapi.fileEditor.impl.EditorWindow;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.NlsSafe;
import com.intellij.openapi.util.UserDataHolderBase;
import com.intellij.openapi.vfs.VFileProperty;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileSystem;
import com.intellij.openapi.vfs.newvfs.NewVirtualFile;
import com.intellij.openapi.vfs.newvfs.NewVirtualFileSystem;
import com.intellij.openapi.vfs.newvfs.impl.VirtualDirectoryImpl;
import com.intellij.openapi.vfs.newvfs.impl.VirtualFileSystemEntry;
import com.intellij.psi.PsiMethod;
import com.intellij.util.keyFMap.KeyFMap;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.RequiredArgsConstructor;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
import java.util.function.Supplier;

/**
 * @author Franklin
 * @since 2023/07/30 10:01
 */
@EqualsAndHashCode(callSuper = true)
//@RequiredArgsConstructor
@Data
public class ExecuteMethodVirtualFile extends VirtualFile {

    private final PsiMethod psiMethod;
    private final VirtualFile delegate;
    private final ExecuteResult executeResult;
    private final FileType fileType;

    private ExecuteHistoryFormNew executeHistoryFormNew;


    @Override
    public @NotNull @NlsSafe String getName() {
        return this.delegate.getName();
    }

    @Override
    public @NotNull VirtualFileSystem getFileSystem() {
        return this.delegate.getFileSystem();
    }

    @Override
    public @NonNls @NotNull String getPath() {
        return this.delegate.getPath();
    }

    @Override
    public @NotNull FileType getFileType() {
        return this.fileType;
    }

    @Override
    public @Nullable @NlsSafe String getExtension() {
        return this.delegate.getExtension();
    }

    @Override
    public @NotNull @NlsSafe CharSequence getNameSequence() {
        return this.delegate.getNameSequence();
    }

    @Override
    public @NotNull Path toNioPath() {
        return this.delegate.toNioPath();
    }

    @Override
    public @NotNull String getUrl() {
        return this.delegate.getUrl();
    }

    @Override
    public @NlsSafe @NotNull String getNameWithoutExtension() {
        return this.delegate.getNameWithoutExtension();
    }

    @Override
    public void rename(Object requestor, @NotNull @NonNls String newName) throws IOException {
        this.delegate.rename(requestor, newName);
    }

    @Override
    public void setWritable(boolean writable) throws IOException {
        this.delegate.setWritable(writable);
    }

    @Override
    public boolean is(@NotNull VFileProperty property) {
        return this.delegate.is(property);
    }

    @Override
    public @Nullable String getCanonicalPath() {
        return this.delegate.getCanonicalPath();
    }

    @Override
    public @Nullable VirtualFile getCanonicalFile() {
        return this.delegate.getCanonicalFile();
    }

    @Override
    public @Nullable VirtualFile findChild(@NotNull @NonNls String name) {
        return this.delegate.findChild(name);
    }

    @Override
    public @NotNull VirtualFile findOrCreateChildData(Object requestor, @NotNull @NonNls String name) throws IOException {
        return this.delegate.findOrCreateChildData(requestor, name);
    }

    @Override
    public @Nullable VirtualFile findFileByRelativePath(@NotNull @NonNls String relPath) {
        return this.delegate.findFileByRelativePath(relPath);
    }

    @Override
    public @NotNull VirtualFile createChildDirectory(Object requestor, @NotNull @NonNls String name) throws IOException {
        return this.delegate.createChildDirectory(requestor, name);
    }

    @Override
    public @NotNull VirtualFile createChildData(Object requestor, @NotNull @NonNls String name) throws IOException {
        return this.delegate.createChildData(requestor, name);
    }

    @Override
    public void delete(Object requestor) throws IOException {
        this.delegate.delete(requestor);
    }

    @Override
    public void move(Object requestor, @NotNull VirtualFile newParent) throws IOException {
        this.delegate.move(requestor, newParent);
    }

    @Override
    public @NotNull VirtualFile copy(Object requestor, @NotNull VirtualFile newParent, @NotNull @NonNls String copyName) throws IOException {
        return this.delegate.copy(requestor, newParent, copyName);
    }

    @Override
    public @NotNull Charset getCharset() {
        return this.delegate.getCharset();
    }

    @Override
    public void setCharset(Charset charset) {
        this.delegate.setCharset(charset);
    }

    @Override
    public void setCharset(Charset charset, @Nullable Runnable whenChanged) {
        this.delegate.setCharset(charset, whenChanged);
    }

    @Override
    public void setCharset(Charset charset, @Nullable Runnable whenChanged, boolean fireEventsWhenChanged) {
        this.delegate.setCharset(charset, whenChanged, fireEventsWhenChanged);
    }

    @Override
    public boolean isCharsetSet() {
        return this.delegate.isCharsetSet();
    }

    @Override
    public void setBinaryContent(byte @NotNull [] content, long newModificationStamp, long newTimeStamp) throws IOException {
        this.delegate.setBinaryContent(content, newModificationStamp, newTimeStamp);
    }

    @Override
    public void setBinaryContent(byte @NotNull [] content, long newModificationStamp, long newTimeStamp, Object requestor) throws IOException {
        this.delegate.setBinaryContent(content, newModificationStamp, newTimeStamp, requestor);
    }

    @Override
    public byte @NotNull [] contentsToByteArray(boolean cacheContent) throws IOException {
        return this.delegate.contentsToByteArray(cacheContent);
    }

    @Override
    public void refresh(boolean asynchronous, boolean recursive) {
        this.delegate.refresh(asynchronous, recursive);
    }

    @Override
    public @NlsSafe String getPresentableName() {
        return this.delegate.getPresentableName();
    }

    @Override
    public long getModificationCount() {
        return this.delegate.getModificationCount();
    }

    @Override
    public byte @Nullable [] getBOM() {
        return this.delegate.getBOM();
    }

    @Override
    public void setBOM(byte @Nullable [] BOM) {
        this.delegate.setBOM(BOM);
    }

    @Override
    public String toString() {
        return this.delegate.toString();
    }

    @Override
    public boolean exists() {
        return this.delegate.exists();
    }

    @Override
    public boolean isInLocalFileSystem() {
        return this.delegate.isInLocalFileSystem();
    }

    @Override
    public @Nullable @NlsSafe String getDetectedLineSeparator() {
        return this.delegate.getDetectedLineSeparator();
    }

    @Override
    public void setDetectedLineSeparator(@Nullable String separator) {
        this.delegate.setDetectedLineSeparator(separator);
    }

    @Override
    public <T> T computeWithPreloadedContentHint(byte @NotNull [] preloadedContentHint, @NotNull Supplier<? extends T> computable) {
        return this.delegate.computeWithPreloadedContentHint(preloadedContentHint, computable);
    }

    @Override
    public String getUserDataString() {
        return this.delegate.getUserDataString();
    }

    @Override
    public void copyUserDataTo(@NotNull UserDataHolderBase other) {
        this.delegate.copyUserDataTo(other);
    }

    @Override
    public <T> T getUserData(@NotNull Key<T> key) {
        return this.delegate.getUserData(key);
    }

    @Override
    public <T> void putUserData(@NotNull Key<T> key, @Nullable T value) {
        this.delegate.putUserData(key, value);
    }

    @Override
    public <T> T getCopyableUserData(@NotNull Key<T> key) {
        return this.delegate.getCopyableUserData(key);
    }

    @Override
    public <T> void putCopyableUserData(@NotNull Key<T> key, T value) {
        this.delegate.putCopyableUserData(key, value);
    }

    @Override
    public <T> boolean replace(@NotNull Key<T> key, @Nullable T oldValue, @Nullable T newValue) {
        return this.delegate.replace(key, oldValue, newValue);
    }

    @Override
    public <T> @NotNull T putUserDataIfAbsent(@NotNull Key<T> key, @NotNull T value) {
        return this.delegate.putUserDataIfAbsent(key, value);
    }

    @Override
    public void copyCopyableDataTo(@NotNull UserDataHolderBase clone) {
        this.delegate.copyCopyableDataTo(clone);
    }

    @Override
    public boolean isUserDataEmpty() {
        return this.delegate.isUserDataEmpty();
    }

    @Override
    public boolean isWritable() {
        return this.delegate.isWritable();
    }

    @Override
    public boolean isDirectory() {
        return this.delegate.isDirectory();
    }

    @Override
    public boolean isValid() {
        return this.delegate.isValid();
    }

    @Override
    public VirtualFile getParent() {
        return this.delegate.getParent();
    }

    @Override
    public VirtualFile[] getChildren() {
        return this.delegate.getChildren();
    }

    @Override
    public @NotNull OutputStream getOutputStream(Object requestor, long newModificationStamp, long newTimeStamp) throws IOException {
        return this.delegate.getOutputStream(requestor, newModificationStamp, newTimeStamp);
    }

    @Override
    public byte @NotNull [] contentsToByteArray() throws IOException {
        return this.delegate.contentsToByteArray();
    }

    @Override
    public long getTimeStamp() {
        return this.delegate.getTimeStamp();
    }

    @Override
    public long getModificationStamp() {
        return this.delegate.getModificationStamp();
    }

    @Override
    public long getLength() {
        return this.delegate.getLength();
    }

    @Override
    public void refresh(boolean asynchronous, boolean recursive, @Nullable Runnable postRunnable) {
        this.delegate.refresh(asynchronous, recursive, postRunnable);
    }

    @Override
    public InputStream getInputStream() throws IOException {
        return this.delegate.getInputStream();
    }

}
